package org.jeecg.interceptor;


import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.OnlineAuth;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.api.dto.OnlineAuthDTO;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.online.cgform.service.IOnlineBaseAPI;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * Online 自定义请求拦截器
 */
@Slf4j
public class OnlineInterceptor implements HandlerInterceptor {

    private IOnlineBaseAPI onlineBaseAPI;

    private ISysBaseAPI sysBaseAPI;

    /**
     * online表单菜单地址
     */
    private static final String ONLINE_FORM = "/online/cgform";

    /**
     * online功能测试地址 前缀
     */
    private static final String[] ONLINE_TEST_PRE = {"/online/cgformInnerTableList","/online/cgformErpList", "/online/cgformList", "/online/cgformTreeList","/online/cgformTabList"};

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 请求的方法是否有注解
        boolean anno = handler.getClass().isAssignableFrom(HandlerMethod.class);
        if (anno) {
            OnlineAuth onlineAuth = ((HandlerMethod) handler).getMethodAnnotation(OnlineAuth.class);
            if (onlineAuth != null) {
                //log.debug("===== online 菜单访问拦截器 =====");
                String requestPath = request.getRequestURI().substring(request.getContextPath().length());
                requestPath = filterUrl(requestPath);
                //1.通过前端请求地址得到code
                String authKey = onlineAuth.value();
                String code = requestPath.substring(requestPath.lastIndexOf(authKey) + authKey.length());
                //log.debug("拦截请求(" + request.getMethod() + ")：" + requestPath + ",");
                if ("form".equals(authKey) && "DELETE".equals(request.getMethod())) {
                    code = code.substring(0, code.lastIndexOf("/"));
                }
                //update-begin-author:taoyan date:20200714 for:子表权限走主表配置
                String onlineTableType = request.getParameter("tabletype");
                if(onlineBaseAPI==null){
                    //单例模式 下可这么处理
                    onlineBaseAPI = SpringContextUtils.getBean(IOnlineBaseAPI.class);
                }
                code = onlineBaseAPI.getOnlineErpCode(code, onlineTableType);
                //update-end-author:taoyan date:20200714 for:子表权限走主表配置
                // Q/hdrTigVhn2pSGe4h016YLAYGNvwZkHHabjkkA48Sh5mbH49xzVfTfEW3ALHDRXupi+Y/Gg/swwGEyL0PuVFg==
                List<String> possibleUrl = new ArrayList<>();
                //获取可能的表单地址
                for (String pre : ONLINE_TEST_PRE) {
                    possibleUrl.add(pre + code);
                }

                if(sysBaseAPI==null){
                    //单例模式 下可这么处理
                    sysBaseAPI = SpringContextUtils.getBean(ISysBaseAPI.class);
                }
                String username = JwtUtil.getUserNameByToken(request);
                OnlineAuthDTO dto = new OnlineAuthDTO(username, possibleUrl, ONLINE_FORM);
                boolean hasPermission = sysBaseAPI.hasOnlineAuth(dto);
                if (!hasPermission) {
                    //log.info("请求无权限(" + request.getMethod() + ")：" + requestPath);
                    backError(response, authKey);
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 地址过滤
     *
     * @param requestPath
     * @return
     */
    private String filterUrl(String requestPath) {
        String url = "";
        if (oConvertUtils.isNotEmpty(requestPath)) {
            url = requestPath.replace("\\", "/");
            url = url.replace("//", "/");
            if (url.indexOf("//") >= 0) {
                url = filterUrl(url);
            }
        }
        return url;
    }

    /**
     * 返回一个错误信息
     *
     * @param response
     * @param authKey
     */
    private void backError(HttpServletResponse response, String authKey) {
        PrintWriter writer = null;
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        response.setHeader("auth", "fail");
        try {
            writer = response.getWriter();
            if ("exportXls".equals(authKey)) {
                writer.print("");
            } else {
                Result<?> result = Result.error("无权限访问(操作)");
                writer.print(JSON.toJSON(result));
            }
        } catch (IOException e) {
            log.error(e.getMessage());
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }
}
